//
//  SSNetworkTools.swift
//  MyMicroBlog
//
//  Created by stevenSu on 15/7/29.
//  Copyright © 2015年 stevenSu. All rights reserved.
//

import UIKit
import AFNetworking
private let SSErrorDomainName = "com.ruihai.error.network"
typealias SSCompletionCallBack = (result: [String: AnyObject]?, error: NSError?) -> ()
class SSNetworkTools: AFHTTPSessionManager {
    // 错误枚举
    enum SSErrorType: Int {
        case blankDataError = -1
        case blankTokenError = -2
        private var description: String {
            switch self {
            case .blankDataError:
                return "空数据"
            case .blankTokenError:
                return "未登录"
            }
        }
        private func error() -> NSError {
            return NSError(domain: SSErrorDomainName, code: rawValue, userInfo: [SSErrorDomainName: description])
        }
    }
    // 网络请求枚举
    enum SSRequestType: String {
        case GET = "GET"
        case POST = "POST"
    }
    
    private var clientID = "2999391721"
    private var clientSecret = "bf9e0efc0937cbe688f5928744cef6ab"
    var redirectURI = "http://www.baidu.com"
    // 单例
    static let sharedNetworkTools: SSNetworkTools = {
        let url = NSURL(string: "https://api.weibo.com/")
        let tool = SSNetworkTools(baseURL: url)
        tool.responseSerializer.acceptableContentTypes = NSSet(objects: "application/json", "text/json", "text/javascript", "text/plain") as Set<NSObject>
        return tool
    }()
    // 登录页
    var oauthURL: NSURL {
        return NSURL(string: "https://api.weibo.com/oauth2/authorize?client_id=\(clientID)&redirect_uri=\(redirectURI)")!
    }
    
    /// 获取token
    /// - parameter code      : 授权码
    func loadAccessToken(code: String, completion: SSCompletionCallBack) {
        let urlString = "oauth2/access_token"
        let params = ["client_id": clientID,
            "client_secret": clientSecret,
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": redirectURI]
        print("loadAccessToken")
        loadURL(SSRequestType.POST, urlStr: urlString, params: params, completion: completion)
    }
    
    /// 获取当前登录用户及其所关注用户的最新微博
    func loadUserStatus(since_id: Int, max_id: Int, completion: SSCompletionCallBack) {
        if var params = checkToken(completion) {
            let urlString = "2/statuses/home_timeline.json"
            print("loadUserStatus")
            if since_id > 0 {
                params["since_id"] = since_id
            }
            if max_id > 0 {
                params["max_id"] = max_id - 1
            }
            
            loadURL(SSRequestType.GET, urlStr: urlString, params: params, completion: completion)
        }
    }
    
    /// 获取用户信息
    func loadUserInfo(completion: SSCompletionCallBack) {
        // 拼接params
        guard var params = checkToken(completion) else {
            return
        }
        let urlString = "2/users/show.json"
        params["uid"] = SSUserToken.loadToken()!.uid
        print("loadUserInfo")
        loadURL(SSRequestType.GET, urlStr: urlString, params: params, completion: completion)
    }
    
    /// 发微博
    func postStatus(status: String, image: UIImage?, completion: SSCompletionCallBack) {
        guard var params = checkToken(completion) else {
            return
        }
        params["status"] = status
        if image == nil {
            let urlString = "2/statuses/update.json"
            print("postStatus")
            loadURL(SSRequestType.POST, urlStr: urlString, params: params, completion: completion)
        } else {
            let urlString = "https://upload.api.weibo.com/2/statuses/upload.json"
            postImageStatus(urlString, image: image!, params: params, completion: completion)
        }
        
    }
    
    private func checkToken(completion: SSCompletionCallBack) -> [String: AnyObject]? {
        // 判断用户是否登录
        if SSUserToken.loadToken() == nil {
            // 应该让用户登录？
            completion(result: nil, error: SSErrorType.blankTokenError.error())
            return nil
        }
        let userToken = SSUserToken.loadToken()!
        return ["access_token": userToken.access_token!]
    }
    
    private func postImageStatus(urlStr: String, image: UIImage, params: [String: AnyObject], completion: SSCompletionCallBack) {
        let success: (NSURLSessionDataTask!, AnyObject!) -> Void = { (_, JSON) -> Void in
            if let result = JSON as? [String: AnyObject] {
                // 有结果的回调
                completion(result: result, error: nil)
            } else {
                // 没错误，也没结果的回调
                completion(result: nil, error: SSErrorType.blankDataError.error())
            }
        }
        let failure: (NSURLSessionDataTask!, NSError!) -> Void = { (_, error) -> Void in
            print(error)
            completion(result: nil, error: error)
        }
        POST(urlStr, parameters: params, constructingBodyWithBlock: { (mdata) -> Void in
            let imgData = UIImagePNGRepresentation(image)
            mdata.appendPartWithFileData(imgData, name: "pic", fileName: "justforfun", mimeType: "application/octet-stream")
            }, success: success, failure: failure)
    }
    
    private func loadURL(requestType: SSRequestType, urlStr: String, params: [String: AnyObject], completion: SSCompletionCallBack) {
        let success: (NSURLSessionDataTask!, AnyObject!) -> Void = { (_, JSON) -> Void in
            if let result = JSON as? [String: AnyObject] {
                // 有结果的回调
                completion(result: result, error: nil)
            } else {
                // 没错误，也没结果的回调
                completion(result: nil, error: SSErrorType.blankDataError.error())
            }
        }
        let failure: (NSURLSessionDataTask!, NSError!) -> Void = { (_, error) -> Void in
            print(error)
            completion(result: nil, error: error)
        }

        switch requestType {
        case .GET:
            GET(urlStr, parameters: params, success: success, failure: failure)
        case .POST:
            POST(urlStr, parameters: params, success: success, failure: failure)
        }
    }
}
